home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok59.lha
/
AmokEd_V1.02b
/
txt
/
EdDisplay.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
11KB
|
383 lines
(*************************************************************************
:Program. EdDisplay.mod
:Contents. Screen- and Gadget-Routines for AmokEd
:Author. Hartmut Goebel
:Language. Oberon
:Translator. Amiga Oberon V1.17.1
:Imports. SupLib (Hartmut Goebel)
:History. V0.1 03 Dec 1990, Hartmut Goebel [hG]
:History. V1.0 02 Apr 1991 [hG]
:Date. 17 Oct 1991 20:49:23
*************************************************************************)
(*
Dieses Modul enthält alle Prozeduren, die für die Steuerung der Bildschirm-
Ein-/Ausgabe nötig sind, sowie die zugehörigen Kommandos.
*)
MODULE EdDisplay;
IMPORT
e : Exec,
edE: EdErrors,
edG: EdGlobalVars,
edL: EdLowLevel,
g : Graphics,
I : Intuition,
lst: EdLists,
ol : OberonLib,
sl : SupLib,
str: Strings,
sys: SYSTEM;
CONST
NoPropFonts = "No Proportional Fonts!!";
UnableToFindFont = "Unable to find font";
PROCEDURE ColT* (n{0}: INTEGER): INTEGER;
BEGIN RETURN (edG.XTBase + n * edG.XSize); END ColT;
PROCEDURE RowT* (n{0}: INTEGER): INTEGER;
BEGIN RETURN (edG.YTBase + n * edG.YSize); END RowT;
PROCEDURE Col* (n{0}: INTEGER): INTEGER;
BEGIN RETURN (edG.XBase + n * edG.XSize); END Col;
PROCEDURE Row* (n{0}: INTEGER): INTEGER;
BEGIN RETURN (edG.YBase + n * edG.YSize); END Row;
PROCEDURE SetPen*(Line: LONGINT);
VAR
Pen : SHORTINT;
BEGIN
Pen := 1;
IF (Line>=edG.Block.SNum) AND (Line<=edG.Block.ENum)
AND ~(edG.commLineMode IN edG.Status) THEN
Pen := 2;
END;
IF (edG.Config.screenDepth = 1)
OR ((edG.WBScreenDepth = 1) AND (edG.Screen = NIL)) THEN
g.SetAPen(edG.RPort,1);
IF Pen = 1 THEN
g.SetDrMd(edG.RPort,g.jam2);
ELSE
g.SetDrMd(edG.RPort,SHORTSET{g.inversvid}+g.jam2);
END;
ELSIF Pen # edG.RPort.fgPen THEN
g.SetAPen(edG.RPort,Pen);
END;
END SetPen;
PROCEDURE TextCursor*(on:BOOLEAN);
VAR
buf : edG.StringPtr;
px, py: INTEGER;
Block: BOOLEAN;
BEGIN
IF NOT (edG.noCursor IN edG.Status) THEN
edL.MoveToCursor;
Block := (edG.Text=edG.Block.Owner) AND (edG.Text.line>=edG.Block.SNum)
AND (edG.Text.line<=edG.Block.ENum);
g.SetAPen(edG.RPort,1);
IF on THEN
g.SetDrMd(edG.RPort,SHORTSET{g.complement});
px := Col(edG.Text.pos-edG.Text.topPos);
py := Row(SHORT(edG.Text.line-edG.Text.topLine));
g.RectFill(edG.RPort,px,py,px+edG.XSize-1,py+edG.YSize-1);
ELSE
g.SetDrMd(edG.RPort,g.jam2);
IF Block AND (edG.Text.pos<=edG.LineBufferLen)
AND (edG.Config.screenDepth = 1) THEN
g.SetDrMd(edG.RPort,SHORTSET{g.inversvid}+g.jam2);
END;
IF Block AND (edG.Config.screenDepth # 1)
AND NOT(edG.commLineMode IN edG.Status) THEN
g.SetAPen(edG.RPort,2); END;
buf := sys.ADR(edG.LineBuffer[edG.Text.pos]);
IF buf[0] # 0X THEN
g.Text(edG.RPort,buf^,1);
ELSE
g.Text(edG.RPort,edG.Spaces,1);
END;
END;
g.SetDrMd(edG.RPort,g.jam2);
END;
END TextCursor;
(*----------------------------------------------------------------------*)
PROCEDURE SetWindowParams*;
VAR
win: I.WindowPtr;
BEGIN
win := edG.Text.window;
edG.RPort := win.rPort;
edG.XSize := edG.RPort.font.xSize;
edG.YSize := edG.RPort.font.ySize;
edG.XBase := win.borderLeft;
edG.YBase := win.borderTop;
edG.XPixs := win.width-win.borderRight-edG.XBase;
edG.YPixs := win.height-win.borderBottom-edG.YBase;
edG.Columns := edG.XPixs DIV edG.XSize;
edG.Rows := edG.YPixs DIV edG.YSize;
edG.XTBase := edG.XBase;
edG.YTBase := edG.YBase+edG.RPort.font.baseline;
IF NOT (edG.iconMode IN edG.Text.status) THEN edG.SetPropKnob; END;
END SetWindowParams;
(*----------------------------------------------------------------------*)
(* bringt ab <start> <n> Zeilen auf den Bildschirm, hiezu müssen *)
(* edG.Text.topLinePtr und edG.Text.actLinePtr den aktuellen Wert haben *)
PROCEDURE TextDisplaySeg*(start, n: INTEGER);
VAR
i,c: INTEGER;
ptr: edG.StringPtr;
thisLine: edG.LinePtr;
BEGIN
IF edG.NoScreenUpdate > 0 THEN RETURN; END;
thisLine := edG.Text.topLinePtr;
IF NOT (edG.commLineMode IN edG.Status) THEN
lst.GoForwardNil(thisLine,start); END;
i := start;
WHILE (i < start+n) AND (i < edG.Rows) AND (thisLine#NIL) DO
IF edG.commLineMode IN edG.Status THEN
ptr := sys.ADR(edG.LineBuffer);
g.SetAPen(edG.RPort,1);
ELSIF (thisLine = edG.Text.actLinePtr) THEN
ptr := sys.ADR(edG.LineBuffer);
SetPen(edG.Text.line);
ELSE
ptr := thisLine(edG.Line).string;
SetPen(edG.Text.topLine+i);
END; (* IF *)
c := str.Length(ptr^)-edG.Text.topPos;
IF c > 0 THEN
INC(ptr,edG.Text.topPos);
g.Move(edG.RPort,ColT(0),RowT(i));
IF c > edG.Columns THEN c := edG.Columns; END;
g.Text(edG.RPort,ptr^,c);
END;
INC(i);
thisLine := thisLine.next(edG.Line);
END (* WHILE *)
END TextDisplaySeg;
PROCEDURE TextRedisplay*;
BEGIN
IF edG.NoScreenUpdate > 0 THEN
RETURN; END;
g.SetAPen(edG.RPort,0);
IF edG.commLineMode IN edG.Status THEN
g.RectFill(edG.RPort,Col(0),Row(edG.Rows-1),
edG.XBase+edG.XPixs,edG.YBase+edG.YPixs);
ELSE
g.RectFill(edG.RPort, edG.XBase, edG.YBase,
edG.XBase+edG.XPixs, edG.YBase+edG.YPixs);
END;
TextDisplaySeg(0,edG.Rows);
(*edG.SetProp; (* eben nicht SetPropKnob!*) *)
END TextRedisplay;
PROCEDURE TextRedisplayCurrentLine*;
VAR
row: INTEGER;
BEGIN
IF edG.NoScreenUpdate > 0 THEN
RETURN; END;
row := SHORT(edG.Text.line-edG.Text.topLine);
g.SetAPen(edG.RPort,0);
g.RectFill(edG.RPort, Col(0), Row(row),
edG.XBase+edG.XPixs, Row(row+1)-1);
TextDisplaySeg(row,1);
END TextRedisplayCurrentLine;
(*------------------------------------------------------------------------
* Syncronisiert den Bildschirm mit dem Text bezüglich der aktuellen
* Werte edG.Text.line, edG.Text.pos und edG.Text.actLinePtr
* Anwendung: line, pos und actLinePtr setzten, TextSync aufrufen
*)
PROCEDURE TextSync*;
VAR
redraw : BOOLEAN;
BEGIN
redraw := FALSE;
IF NOT (edG.NoScreenUpdate > 0) THEN
IF (edG.Text.pos - edG.Text.topPos >= edG.Columns)
OR (edG.Text.pos < edG.Text.topPos) THEN
redraw := TRUE;
edG.Text.topPos := edG.Text.pos - edG.Columns DIV 2;
IF edG.Text.topPos < 0 THEN edG.Text.topPos := 0; END;
END;
IF (edG.Text.line - edG.Text.topLine >= edG.Rows)
OR (edG.Text.line < edG.Text.topLine) THEN
redraw := TRUE;
edG.Text.topLine := edG.Text.line - edG.Rows DIV 2;
IF edG.Text.topLine < 0 THEN edG.Text.topLine := 0; END;
edG.Text.topLinePtr := edG.Text.actLinePtr;
lst.GoBackwardNil(edG.Text.topLinePtr,edG.Text.line-edG.Text.topLine);
END;
END; (* NOT NoScreenUpdate *)
edL.FillUpSpaces;
IF redraw THEN
INCL(edG.Status,edG.alreadyRedrawn);
TextRedisplay;
ELSE
EXCL(edG.Status,edG.alreadyRedrawn);
END;
END TextSync;
(*------------------------------------------------------------------------
*
* Kopiert den ZeilenPuffer nach Entfernen der Spaces
* am Zeilenende in die Aktuelle Zeile
*)
PROCEDURE PutBackLine*;
VAR
thisLine: edG.LinePtr;
ptr: edG.StringPtr;
len, neededSpace : INTEGER;
BEGIN
edL.StripEndSpaces;
len := edG.LineBufferLen;
IF NOT (edG.commLineMode IN edG.Status) THEN
thisLine := edG.Text.actLinePtr;
WITH thisLine:edG.Line DO
IF (thisLine.string^ # edG.LineBuffer) THEN
INCL(edG.Text.status,edG.modified);
EXCL(edG.Text.status,edG.quit); (* explizit: sicher ist sicher! *)
neededSpace := len+edG.ChunkSize-(len MOD edG.ChunkSize);
IF neededSpace # thisLine.len THEN (* anderer Platzbedarf? *)
ptr := e.AllocMem(neededSpace,LONGSET{});
IF ptr # NIL THEN
e.FreeMem(thisLine.string,thisLine.len);
thisLine.string := ptr;
thisLine.len := neededSpace;
ELSE
INCL(edG.Status,edG.memoryFail);
edG.LineBufferLen := thisLine.len;
e.CopyMemQuick(edG.LineBuffer,thisLine.string^,edG.LineBufferLen);
thisLine.string[edG.LineBufferLen] := 0X;
RETURN;
END; (* IF ptr # NIL *)
END; (* IF neededSpace # thisLine.len *)
e.CopyMemQuick(edG.LineBuffer,thisLine.string^,neededSpace);
END; (* IF thisLine.string^ # edG.LineBuffer *)
END; (* WITH *)
END; (* NOT commLineMode *)
END PutBackLine;
(* Holt aktuelle Zeile in den ZeilenPuffer *)
PROCEDURE TextLoad*;
BEGIN
IF edG.commLineMode IN edG.Status THEN RETURN; END;
e.CopyMemQuick(edG.Text.actLinePtr(edG.Line).string^,edG.LineBuffer,
edG.Text.actLinePtr(edG.Line).len);
edG.LineBufferLen := str.Length(edG.LineBuffer);
edL.FillUpSpaces;
END TextLoad;
(*----------------------------------------------------------------------*)
PROCEDURE TextPosition*(col, row: INTEGER);
BEGIN
PutBackLine;
IF col = 0 THEN col := -1; END;
edG.Text.pos := edG.Text.topPos+col;
IF edG.Text.pos > edG.MaxLineLength-2 THEN edG.Text.pos := edG.MaxLineLength-2;
ELSIF edG.Text.pos < 0 THEN edG.Text.pos := 0 END;
edG.Text.line := edG.Text.topLine+row;
edG.Text.actLinePtr := edG.Text.topLinePtr;
IF row > 0 THEN
IF edG.Text.line >= edG.Text.numberOfLines THEN
edG.Text.line := edG.Text.numberOfLines-1; END;
lst.GoForwardNil(edG.Text.actLinePtr,edG.Text.line-edG.Text.topLine);
ELSIF row < 0 THEN
lst.GoBackwardNil(edG.Text.actLinePtr,-row);
IF edG.Text.line <= 0 THEN
edG.Text.actLinePtr := edG.Text.lineList.head;
edG.Text.line := 0;
END;
END;
TextLoad;
TextSync;
END TextPosition;
(*----------------------------------------------------------------------*)
(* Schaltet Editior auf <txt> um *)
PROCEDURE SwitchEdit*(txt: edG.TextHeaderPtr);
BEGIN
PutBackLine;
IF NOT (edG.iconMode IN edG.Text.status) THEN edL.WindowTitle; END;
edG.Text := txt;
SetWindowParams;
TextLoad;
IF NOT (edG.iconMode IN edG.Text.status) THEN TextSync; END;
(*edL.WindowTitle;*)
END SwitchEdit;
(*----------------------------------------------------------------------*)
(* patch to speed up scrolling *)
PROCEDURE FastScrollRaster*(dx,dy,l,t,w,h: INTEGER);
VAR
depth: POINTER TO BYTE;
old: BYTE;
BEGIN
depth := sys.ADR(edG.RPort.bitMap.depth);
old := depth^;
e.Forbid();
IF (edG.Block.SNum > edG.Text.topLine + edG.Rows)
OR (edG.Block.ENum < edG.Text.topLine - 1) THEN
depth^ := 1;
END;
g.ScrollRaster(edG.RPort,dx,dy,l,t,w,h);
depth^ := old;
e.Permit();
END FastScrollRaster;
(*----------------------------------------------------------------------*)
PROCEDURE doSetFont*;
VAR
font: g.TextFontPtr;
size: LONGINT;
BEGIN
IF NOT edL.StrToInt(edG.Arg[1],size) OR (size > MAX(INTEGER)) THEN
edL.Title(edG.BadArgument); edG.Rc := edE.cmdError;
RETURN;
END;
font := sl.GetFont(edG.Arg[0]^,SHORT(size));
IF font # NIL THEN
IF g.proportional IN font.flags THEN
g.CloseFont(font);
edL.Title(NoPropFonts); edG.Rc := edE.cmdFailed;
RETURN;
END;
IF edG.Text.font # NIL THEN
g.CloseFont(edG.Text.font); END;
edG.Text.font := font;
g.SetFont(edG.Text.window.rPort,font);
g.SetRast(edG.Text.window.rPort,0);
I.RefreshWindowFrame(edG.Text.window);
SetWindowParams;
TextSync;
IF NOT (edG.alreadyRedrawn IN edG.Status) THEN TextRedisplay; END;
ELSE
edL.Title(UnableToFindFont); edG.Rc := edE.cmdFailed;
END;
END doSetFont;
END EdDisplay.